//1.创建舞台、场景
var canvas = document.getElementById('canvas');
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var stage = new JTopo.Stage(canvas);
var scene = new JTopo.Scene(stage);
var startIndex = 1;
var nodeIdPrefix = "node";
var linkPrefix = "link";
var defaultSpace = 15;
var startX = 100;
var startY = 100;
var defaultWH = 40;
var cubesNum = 6;
var searchTimes = 0;
var uselessTimes = 0;
var accessWayCnt = 0;
var uselessPoint = [];

var nodeTool = function () {
    return {
        /**
         * 获得随机的结点,用于创建障碍
         * @param max
         * @param num
         */
        getRandomPointList: function (max, num) {
            var list = [];
            for (var i=0;;i++){
                var temp = parseInt(Math.random()*max*Math.random()*max)+1;

                if(util.contains(list,temp)<0 && list.length<num){
                    list.push(temp);
                }

                if(list.length==num){
                    break;
                }
            }
            uselessPoint = list;
        },

        /**
         * 创建node,单个
         * @param param
         * @returns {c|*}
         * @private
         */
        _createNode: function (param) {
            var node = new JTopo.Node();
            for (var key in param) {
                if (param[key] != undefined) {
                    node[key] = param[key];
                }
            }
            if(util.contains(uselessPoint,startIndex)>0){
                node.alpha = 0.5;
            }
            node.id = nodeIdPrefix + startIndex;
            node.nodeIndex = startIndex;
            node.dragable = false;
            node.text = startIndex;
            node.textOffsetY = -20;
            this.addEvent(node);
            startIndex++;
            scene.add(node);
            return node;
        },
        /**
         * 创建node ,多个
         * @param param
         * @returns {*}
         */
        createNodes: function (param) {
            if (param instanceof Array) {
                var nodes = [];
                for (var index = 0; index < param.length; index++) {
                    nodes.push(this._createNode(param[index]));
                }
                return nodes;
            } else {
                return this._createNode(param);
            }
        },
        /**
         * 连接node
         * @param nodeA
         * @param nodeZ
         * @param color
         * @param text
         * @returns {f|*}
         */
        linkNode: function (nodeA, nodeZ, color, text) {
            var text1 = text || "";
            var link = new JTopo.Link(nodeA, nodeZ, text1);
            link.lineWidth = 3; // 线宽
            link.strokeColor = color || '0,200,255';
            scene.add(link);
            return link;
        },
        /**
         * 删除node
         * @param nodeId
         */
        deleteNode: function (nodeId) {
            var node = this.findNode(nodeId);
            scene.remove(node);
        },

        /**
         * 查找元素
         * @param elementId
         */
        findNode: function (elementId) {
            return scene.findElements(function (e) {
                return e.id == elementId;
            })[0];
        },

        /**
         * 查找元素,多个
         * @param elementIds
         * @returns {Array}
         */
        findNodes: function (elementIds) {
            var results = [];
            for(var i=0;i<elementIds.length;i++){
                var temp =  this.findNode(elementIds[i]);
                if(temp){
                    results.push(temp);
                }
            }
            return results;
        },
        /**
         * 更改元素的属性
         * @param nodeId
         * @param param
         */
        changeNode: function (nodeId, param) {
            var node = this.findNode(nodeId);
            for (var key in param) {
                if (param[key] != undefined) {
                    node[key] = param[key];
                }
            }
        },
        /**
         * 批量更改元素属性
         * @param ids
         * @param param
         */
        changeNodes:function (nodeIds,param) {
            for(var i=0;i<nodeIds.length;i++){
                this.changeNode(nodeIds[i],param);
            }
        },
        /**
         * 移动结点
         * @param nodeId
         * @param direction
         * @param distance
         */
        moveNode: function (nodeId, direction, distance) {
            var node = this.findNode(nodeId);
            var x = node.x;
            var y = node.y;
            switch (direction) {
                case "up":
                    node.setLocation(x, y + distance);
                    break;
                case "left":
                    node.setLocation(x - distance, y);
                    break;
                case "right":
                    node.setLocation(x + distance, y);
                    break;
                case "down":
                    node.setLocation(x, y - distance);
                    break;
            }
        },

        /**
         * 添加事件
         * @param node
         */
        addEvent: function (node) {
            var id = node.id;
            var color = node.fillColor;
            node.click(function (event) {

            });

            node.mouseover(function (event) {
                nodeTool.changeNode(id, {fillColor: "0,0,0"});
            });

            node.mouseout(function (event) {
                nodeTool.changeNode(id, {fillColor: color});
            });
        },
        /**
         * 连接节点,多个
         * @param nodeIdList
         * @param color
         */
        linkNodes: function (nodeIdList, color) {
            for (var index = 0; index < nodeIdList.length - 1; index++) {
                var id1 = nodeIdList[index];
                var id2 = nodeIdList[index + 1];
                var node1 = this.findNode(nodeIdPrefix + id1);
                var node2 = this.findNode(nodeIdPrefix + id2);
                this.linkNode(node1, node2, color);
            }
        },
        /**
         * 连接节点,节点与节点之间连接,非直连
         * @param index1
         * @param index2
         * @returns {boolean}
         */
        linkNodesByNode: function (index1, index2) {
            var big = index1 > index2 ? index1 : index2;
            var small = index1 > index2 ? index2 : index1;
            if (big > cubesNum * cubesNum || small < 1) {
                return false;
            }
            var wayLists = [];
            this.findWay(wayLists, [small], small, big);
            wayLists = this.wayFilter(wayLists);
            for (var i = 0; i < wayLists.length; i++) {
                this.linkNodes(wayLists[i], this.getRandomColor());
            }
        },
        /**
         * 查找可用路径
         * @param targetList
         * @param wayList
         * @param smallIndex
         * @param targetIndex
         * @returns {boolean}
         */
        findWay: function (targetList, wayList, smallIndex, targetIndex) {
            searchTimes++;
            var currentChoices = this.getNeighborIndexList(smallIndex);
            var temp = util.contains(currentChoices, targetIndex);
            var startIndex = 0;
            var length = currentChoices.length;
            if (temp >= 0) {
                startIndex = temp;
                length = temp + 1;
            }
            for (var i = startIndex; i < length; i++) {
                var tempIndex = currentChoices[i];
                if (util.contains(wayList, tempIndex) == -1 && wayList.length <= (cubesNum * 2 - 2)) {
                    if (tempIndex != targetIndex && tempIndex < (targetIndex + wayList[0] + 1)) {
                        var newList = wayList.slice();
                        newList.push(tempIndex);
                        var re = this.findWay(targetList, newList, tempIndex, targetIndex);
                        if (re === true) {
                            break;
                        }
                    } else if (tempIndex == targetIndex) {//通路
                        wayList.push(tempIndex);
                        if (this.getBreakingPointNum(wayList) <= 2) {
                            targetList.push(wayList);
                            accessWayCnt++;
                            return true;
                            break;
                        }
                    } else {
                        uselessTimes++;
                    }
                } else if (util.contains(wayList, tempIndex) == -1 && wayList.length == (cubesNum * 2 - 2)) {
                    uselessTimes++;
                    break;
                }
            }
        },

        /**
         * 路径过滤
         * @param wayLists
         * @returns {Array}
         */
        wayFilter: function (wayLists) {
            var minSize = cubesNum * 2 - 1;
            for (var i = 0; i < wayLists.length; i++) {
                if (wayLists[i].length < minSize) {
                    minSize = wayLists[i].length;
                }
            }
            var newList = [];
            for (var i = 0; i < wayLists.length; i++) {
                if (wayLists[i].length == minSize) {
                    newList.push(wayLists[i]);
                }
            }
            return newList;
        },

        /**
         * 获取节点附近的结点集
         * @param index0
         * @returns {Array}
         */
        getNeighborIndexList: function (index0) {
            var nodeIndex = index0;
            var totalNum = cubesNum * cubesNum;
            var indexList = [];
            var testList = [cubesNum, 1, -1, -cubesNum];
            for (var index = 0; index < testList.length; index++) {
                var testNum = testList[index];
                var temp = nodeIndex + testNum;
                if (temp > 0 && temp <= totalNum && util.contains(uselessPoint,temp) <0 ) {
                    if (nodeIndex % cubesNum <= 1) {
                        if (nodeIndex % cubesNum == 1 && temp % cubesNum != 0) {
                            indexList.push(temp);
                        } else if (nodeIndex % cubesNum == 0 && temp % cubesNum != 1) {
                            indexList.push(temp);
                        }
                    } else {
                        indexList.push(temp);
                    }
                }
            }
            return indexList;
        },
        /**
         * 计算路径包含的转折点
         * @param indexList
         * @returns {number}
         */
        getBreakingPointNum: function (indexList) {
            var pointNum = 0;
            for (var index = 0; index < indexList.length - 2; index++) {
                var nodeIndex1 = indexList[index];
                var nodeIndex2 = indexList[index + 1];
                var nodeIndex3 = indexList[index + 2];
                if ((nodeIndex3 - nodeIndex2) != (nodeIndex2 - nodeIndex1)) {
                    pointNum++;
                }
            }
            return pointNum;
        },

        /**
         *  获取随机颜色
         * @returns {string}
         */
        getRandomColor: function () {
            var color1 = parseInt(Math.random() * 255);
            var color2 = parseInt(Math.random() * 255);
            var color3 = parseInt(Math.random() * 255);
            return color1 + "," + color2 + "," + color3;
        },


        treeNodes:function (index,list) {
            index = index||0;
            var temp = list[index];
            var id = temp.id;
            var pId = temp.pId;
            if(pId>0){

            }
        },


    };
}();

var gameMethod = function () {
    return {
        /**
         * 创建矩阵
         * @param WH
         */
        createCubes: function (WH) {
            if (WH % 2 == 0) {
                var num = WH;
                var totalCubeNum = num * num;
                var colorNum = totalCubeNum / 2;
                for (var index = 0; index < num; index++) {
                    for (var index2 = 0; index2 < num; index2++) {
                        var alpha = 1;
                        //边缘
                        // if (index2 == 0 || index2 + 1 == num || index == 0 || index + 1 == num) {
                        // alpha = 0.5;
                        // }

                        nodeTool.createNodes({
                            alpha: alpha,
                            x: startX + index2 * defaultWH + defaultSpace * index2,
                            y: startY + index * defaultWH + defaultSpace * index,
                        });
                    }
                }
            }
        },


        createGame:function(){
            nodeTool.getRandomPointList(cubesNum,12);//创建随机不可用结点
            this.createCubes(cubesNum);//创建

        },

    };

}();


var util = function () {
    return {
        /**
         * 数组是否包含目标,只判断数值
         * @param list
         * @param num
         * @returns {number}
         */
        contains: function (list, num) {
            for (var i = 0; i < list.length; i++) {
                if (num == list[i]) {
                    return i;
                }
            }
            return -1;
        },

    };
}();


gameMethod.createGame();